package com.jackrain.nea.fc.dl.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.util.TypeUtils;
import com.jackrain.nea.common.*;
import com.jackrain.nea.config.PropertiesConf;
import com.jackrain.nea.core.redis.RedisObjectSerializer;
import com.jackrain.nea.dl.common.utils.esutil.ConvertQueryListUtil;
import com.jackrain.nea.dl.common.utils.esutil.ElasticsearchUtil;
import com.jackrain.nea.exception.NDSException;
import com.jackrain.nea.fc.dl.mapper.ViewDLBillChangeMapper;
import com.jackrain.nea.fc.dl.api.ViewDLBillChangeSaveCmd;
import com.jackrain.nea.fc.utils.Constants;
import com.jackrain.nea.sys.CommandAdapter;
import com.jackrain.nea.util.ApplicationContextHandle;
import com.jackrain.nea.util.ValueHolder;
import com.jackrain.nea.web.face.User;
import com.jackrain.nea.web.query.DefaultWebEvent;
import com.jackrain.nea.web.query.QuerySessionImpl;
import com.jackrain.nea.web.security.Security4Utils;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URI;
import java.net.URISyntaxException;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;

/**
 * 单据状态变更 F4->中间表->FC
 *
 * @author wuwenxue
 * @date 2018/05/11
 **/
@Slf4j
@Component
@Service(protocol = "dubbo", validation = "true", version = "1.0", group = "cp")
public class ViewDLBillChangeSaveCmdImpl extends CommandAdapter implements ViewDLBillChangeSaveCmd {

    @Autowired
    PostHandleEvent postHandleEvent;

    @Autowired
    private ElasticsearchUtil esUtil;

    @Autowired
    private ConvertQueryListUtil convertQLUtil;

    @Autowired
    private BtranEsName btranEsName;

    private Logger accesLogger = LoggerFactory.getLogger(Constants.ACCESS_PARAM_LOGGER);

    @Override
    public ValueHolder execute(HashMap map) throws NDSException {

        ValueHolder vh = new ValueHolder();
        JSONObject param = JSON.parseObject(JSON.toJSONStringWithDateFormat(map.get("param"),
                "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteMapNullValue), Feature.OrderedField);
        if (null == param || param.size() == 0) {
            throw new NDSException("参数格式错误！");
        }
        log.info("ViewDLBillChangeSaveCmdImpl--param-->{}",param);

        ViewDLBillChangeMapper viewDLBillChangeMapper = ApplicationContextHandle.getBean(
                ViewDLBillChangeMapper.class);
        JSONArray paramArray = param.getJSONArray("data");

        JSONArray errorArray = new JSONArray();
        JSONArray successIds = new JSONArray();
        for (int i = 0; i < paramArray.size(); i++) {
            JSONObject errorJson = new JSONObject();
            JSONObject billJson = paramArray.getJSONObject(i);

            JSONObject zbJS = billJson.getJSONObject("DL_T_BILL_STATUS_CHANGE");
            JSONArray itemJS = billJson.getJSONArray("DL_T_BILL_STATUS_CHANGE_ITEM");

            try {

                String billType = zbJS.getString("BILL_TYPE");
                String billNo = zbJS.getString("BILL_NO");
                String statusType = zbJS.getString("STATUS_TYPE");
                String oprdata = zbJS.getString("OPR_DATE");
                String oprEcode = zbJS.getString("OPR_ECODE");
                String idList = zbJS.getString("IDLIST");
                //出库日期/入库
                String storeDate = zbJS.getString("USERDEFINE1");
                BigDecimal sumQty = BigDecimal.ZERO;
                BigDecimal sumAmtOut = BigDecimal.ZERO;

                User user = Security4Utils.getUser(oprEcode);
                QuerySessionImpl querySession = new QuerySessionImpl(user);
                DefaultWebEvent event = new DefaultWebEvent("dlBillChange",
                        new HashMap(16));

                String fcItemTableNmae = "dl_b_tran_item_sku";
                if ("TRAN_OUT".equals(billType)) {
                    Long billId = null;
                    List<Long> billidList = es(billNo, btranEsName.getOuttype());
                    if (billidList != null && billidList.size() > 0) {
                        billId = billidList.get(0);
                    }

                    //发出
                    if ("SEND".equals(statusType)) {
                        /*************处理明细表数据************/
                        JSONArray tranOutArray = new JSONArray();
                        for (int j = 0; j < itemJS.size(); j++) {
                            JSONObject itemJson = itemJS.getJSONObject(j);
                            String sku = itemJson.getString("SKU");
                            String storeCode = itemJson.getString("STORE_CODE");
                            BigDecimal qty = itemJson.getBigDecimal("QTY");
                            sumQty = sumQty.add(qty);

                            JSONObject newItemJson = new JSONObject();
                            HashMap h = viewDLBillChangeMapper.selSkuData(sku);
                            if (null != h && h.size() > 0) {
                                Long skuId = TypeUtils.castToLong(h.get("ID"));
                                newItemJson.put("PS_C_SKU_ID", skuId);
                            } else {
                                throw new NDSException("未查询到对应的条码ID   ECODE：" + sku);
                            }
                            String field = "ID";
                            JSONObject whereJS = new JSONObject();
                            whereJS.put("DL_B_TRAN_ID", billId);
                            whereJS.put("PS_C_SKU_ECODE", sku);
                            HashMap itemIdJson = QueryDLUtil.queryDL(fcItemTableNmae, field, whereJS);
                            if (null != itemIdJson && itemIdJson.size() > 0) {
                                newItemJson.put("ID", itemIdJson.get("ID"));
                            }
                            if (null != h.get("PS_C_PRO_ID")) {
                                Long proId = TypeUtils.castToLong(h.get("PS_C_PRO_ID"));
                                HashMap proh = viewDLBillChangeMapper.selProData(proId);
                                BigDecimal price;
                                if (null != proh && proh.size() > 0) {
                                    price = TypeUtils.castToBigDecimal(proh.get("PRICELIST"));
                                } else {
                                    throw new NDSException("未查询到对应的商品   ID：" + proId);
                                }

                                BigDecimal amtOut = qty.multiply(price);
                                newItemJson.put("AMT_OUT", amtOut);
                                sumAmtOut = sumAmtOut.add(amtOut);
                            }

                            newItemJson.put("QTY_OUT", qty);
                            tranOutArray.add(newItemJson);
                        }

                        /*************处理主表数据************/
                        JSONObject paramJson = new JSONObject();
                        paramJson.put("objid", billId);
                        paramJson.put("STORE_DATE", storeDate);
                        paramJson.put("IS_F4CHECK", "N");
                        paramJson.put("is_check", "Y");
                        JSONObject fixColumn = new JSONObject();
                        JSONObject tranOutJson = new JSONObject();

                        tranOutJson.put("DATE_OUT", oprdata);
                        tranOutJson.put("SUM_QTY_OUT", sumQty);
                        tranOutJson.put("SUM_AMT_LIST_OUT", sumAmtOut);

                        fixColumn.put("DL_B_TRAN_OUT", tranOutJson);
                        fixColumn.put("DL_B_TRAN_OUT_V_ITEM_SKU", tranOutArray);
                        paramJson.put("fixcolumn", fixColumn);

//                        log.info("resultJson==>" + paramJson.toString());
                        accesLogger.info("ViewDLBillChangeSaveCmdImpl--paramJson_sendout-->{}",paramJson);

                        String notic = "com.jackrain.nea.dl.tran.api.BtranoutSendCmd:1.0:dl";

                        event.put("param", paramJson);
                        event.setParameter("command", notic);
                        event.setParameter("table", "DL_B_TRAN_OUT");
                        event.setParameter("webaction", "DL_B_TRAN_OUT_SEND_TRAFFIC_CONFIRM");
                        event.setParameter("isSendMq", "N");
                        querySession.setEvent(event);

                        JSONObject retJo = postHandleEvent.executePostHandle(paramJson, querySession, event, "webaction");
                        accesLogger.info("ViewDLBillChangeSaveCmdImpl--retJo_sendout-->{}",retJo);

                        if (retJo.containsKey("code") && (int) retJo.get("code") != 0) {
                            errorJson.put("key", idList);
                            if (null == retJo.get("message")) {
                                errorJson.put("message", "（单据状态变更）调拨出库单发出操作服务调用异常");
                            } else {
                                errorJson.put("message", "（单据状态变更）调拨出库单发出操作服务调用异常->" + retJo.get("message"));
                            }
                            errorArray.add(errorJson);
                            continue;
                        }

                        successIds.add(idList);

                    } else if ("UNCHK".equals(statusType) || "DEL".equals(statusType)) {
                        String notic;
                        String action;
                        if ("UNCHK".equals(statusType)) {
                            //取消审核
                            notic = "com.jackrain.nea.dl.tran.api.BtranoutUnSubmitCmd:1.0:dl";
                            action = "unsubmit";
                        } else {
                            //作废
                            notic = "com.jackrain.nea.dl.tran.api.BtranoutVoidCmd:1.0:dl";
                            action = "void";
                        }

                        JSONObject paramJson = new JSONObject();
                        paramJson.put("objid", billId);
                        paramJson.put("table", "DL_B_TRAN_OUT");
                        paramJson.put("IS_F4CHECK", "N");
                        event.put("param", paramJson);
                        event.setParameter("isSendMq", "N");
                        querySession.setEvent(event);
//                        log.info("BillChage_Data_UNCHK_DEL->" + paramJson);
                        accesLogger.info("ViewDLBillChangeSaveCmdImpl--paramJson_unsubmit_void-->{}",paramJson);

                        JSONObject retJo = postHandleEvent.executePostHandle(paramJson, querySession, event, action);
//                        log.info("retJo" + retJo);
                        accesLogger.info("ViewDLBillChangeSaveCmdImpl--retJo_unsubmit_void-->{}",retJo);

                        if (retJo.containsKey("code") && (int) retJo.get("code") != 0) {
                            errorJson.put("key", idList);
                            if (null == retJo.get("message")) {
                                errorJson.put("message", "（单据状态变更）调拨出库单" + statusType + "操作服务调用异常");
                            } else {
                                errorJson.put("message", "（单据状态变更）调拨出库单" + statusType + "操作服务调用异常->" +
                                        retJo.get("message"));
                            }
                            errorArray.add(errorJson);
                            continue;
                        }
                        successIds.add(idList);
                    } else {
                        log.debug("单据类型" + billType + "  STATUSTYPE" + statusType);
                        throw new NDSException("非处理类型  " + "单据类型" + billType + "  STATUSTYPE" + statusType);
                    }
                } else if ("TRAN_IN".equals(billType)) {

                    Long billId = null;
                    List<Long> billidList = es(billNo, btranEsName.getIntype());
                    if (billidList != null && billidList.size() > 0) {
                        billId = billidList.get(0);
                    }

                    if ("ACCEPT".equals(statusType)) {
                        JSONArray tranInArray = new JSONArray();
                        for (int j = 0; j < itemJS.size(); j++) {
                            JSONObject itemJson = itemJS.getJSONObject(j);
                            JSONObject newItemJson = new JSONObject();
                            String sku = itemJson.getString("SKU");
                            //明细id
                            String field = "ID";
                            JSONObject whereJS = new JSONObject();
                            whereJS.put("DL_B_TRAN_ID", billId);
                            whereJS.put("PS_C_SKU_ECODE", sku);
                            HashMap itemIdJson = QueryDLUtil.queryDL(fcItemTableNmae, field, whereJS);
                            if (null != itemIdJson && itemIdJson.size() > 0) {
                                newItemJson.put("ID", itemIdJson.get("ID"));
                            }

                            newItemJson.put("QTY_IN", itemJson.get("QTY"));
                            tranInArray.add(newItemJson);
                        }

                        JSONObject tranJo = new JSONObject();
                        JSONObject tranIn = new JSONObject();
                        JSONObject fixColumJo = new JSONObject();
                        fixColumJo.put("DL_B_TRAN_IN", tranIn);
                        fixColumJo.put("DL_B_TRAN_IN_V_ITEM_SKU", tranInArray);
                        tranJo.put("objid", billId);
                        tranJo.put("IS_F4CHECK", "N");
                        tranJo.put("fixcolumn", fixColumJo);
                        tranJo.put("table", "DL_B_TRAN_IN");
                        event.put("param", tranJo);
                        event.setParameter("isSendMq", "N");
                        querySession.setEvent(event);
                        log.info("tranJo==>" + tranJo.toString());
                        accesLogger.info("ViewDLBillChangeSaveCmdImpl--tranJo-->{}",tranJo);

                        JSONObject tranretJo = postHandleEvent.executePostHandle(tranJo, querySession, event, "save");
                        accesLogger.info("ViewDLBillChangeSaveCmdImpl--tranretJo-->{}",tranretJo);

                        if (tranretJo.containsKey("code") && (int) tranretJo.get("code") != 0) {
                            errorJson.put("key", idList);
                            if (null == tranretJo.get("message")) {
                                errorJson.put("message", "（单据状态变更）调拨入库单验收前保存操作服务调用异常");
                            } else {
                                errorJson.put("message", "（单据状态变更）调拨入库单验收前保存操作服务调用异常->" +
                                        tranretJo.get("message"));
                            }
                            errorArray.add(errorJson);
                            continue;
                        }

                        JSONObject paramJson = new JSONObject();
                        paramJson.put("objid", billId);
                        paramJson.put("ARRIVAL_TIME_APPLY", new Timestamp(System.currentTimeMillis()).toString());
                        paramJson.put("STORE_DATE_IN", storeDate);
                        paramJson.put("IS_F4CHECK", "N");
                        paramJson.put("is_check", "Y");
                        JSONObject fixColumn = new JSONObject();
                        fixColumn.put("DL_B_TRAN_IN_V_ITEM_SKU", tranInArray);
                        paramJson.put("fixcolumn", fixColumn);
                        event.put("param", paramJson);
                        querySession.setEvent(event);
                        accesLogger.info("ViewDLBillChangeSaveCmdImpl--paramJson_accept-->{}",paramJson);

                        log.info("paramJson==>" + paramJson.toString());
                        //调用验收服务
                        event.setParameter("command", "com.jackrain.nea.dl.tran.api.BtraninCheckInCmd:1.0:dl");
                        event.setParameter("table", "DL_B_TRAN_IN");
                        event.setParameter("webaction", "DL_B_TRAN_IN_CHECK_S_BEFOR");
                        querySession.setEvent(event);
                        JSONObject retJo = postHandleEvent.executePostHandle(paramJson, querySession, event, "webaction");
                        accesLogger.info("ViewDLBillChangeSaveCmdImpl--retJo_accept-->{}",retJo);

                        if (retJo.containsKey("code") && (int) retJo.get("code") != 0) {
                            errorJson.put("key", idList);
                            if (null == retJo.get("message")) {
                                errorJson.put("message", "（单据状态变更）调拨出库单验收操作服务调用异常");
                            } else {
                                errorJson.put("message", "（单据状态变更）调拨出库单验收操作服务调用异常->" + retJo.get("message"));
                            }
                            errorArray.add(errorJson);
                            continue;
                        }

                        successIds.add(idList);
                    }
                } else {
                    log.debug("单据类型" + billType);
                    throw new NDSException("非处理类型  " + "单据类型" + billType);
                }

            } catch (Exception e) {
                String error = "";
                if ((e instanceof NDSException)) {
                    error = e.getMessage();
                } else {
                    StringWriter sw = new StringWriter();
                    PrintWriter pw = new PrintWriter(sw);
                    e.printStackTrace(pw);
                    error = sw.toString();
                }
                String idList = zbJS.getString("IDLIST");
                errorJson.put("key", idList);
                errorJson.put("message", error);
                errorArray.add(errorJson);
            }
        }

        if (errorArray.size() > 0) {
            vh.put("error", errorArray);
            vh.put("code", -1);
        } else {
            vh.put("code", 0);
        }
        vh.put("successIds", successIds);

        return vh;
    }

    /**
     * ES查询调拨出库单ID
     *
     * @param billNo 单据编号
     * @return id
     */
    public List<Long> es(String billNo, String type) {
        JSONObject bill_no = esUtil.generateMatch("BILL_NO", billNo);
        List<JSONObject> terms = esUtil.packageTerm(bill_no);
        List<Long> longs = null;
        try {
            JSONObject jsonObject = esUtil.searchAllDataByTerms(btranEsName.getIndex(),
                    type, "1", "10000", terms);
            log.debug("es_jsonObject->" + jsonObject);
            longs = convertQLUtil.selectId(jsonObject.toString());
        } catch (IOException e) {
            log.error(e.getMessage());
        }
        return longs;
    }
}
